// tree.cpp
// 04/17/2011 : created

#include "tree.h"

Tree::Tree(dataset_type& data)
  : m_data(data), m_parent(NULL), m_idx(*(new vint_type(m_data.size()))),
  m_s(0), m_e(m_data.size())
{
  for_all_node_data(i) m_idx[i] = i;
}

Tree::Tree(Tree* parent, int s, int e)
  : m_data(parent->m_data), m_parent(parent), m_idx(parent->m_idx), 
  m_s(s), m_e(e)
{
}

Tree::~Tree()
{
  if (!m_parent) {
    delete &m_idx;  // only delete indices in root 
  }
  for (unsigned int i = 0; i < m_child.size(); i++) delete m_child[i];
}

void Tree::findKNN(const vec& query, std::vector<int>& knnIdx, std::vector<double>& minBound)
{
  int K = knnIdx.size();
  for_all_node_data(i) {
    double dist = arma::norm(query-get(i), 2);
    for (int k = 0; k < K; k++) if (dist < minBound[k]) {
      knnIdx.insert(knnIdx.begin()+k, m_s+i); knnIdx.pop_back();
      minBound.insert(minBound.begin()+k, dist); minBound.pop_back();
//        Log::m_log << "i=" << m_s+i << " (" << get(i)[0] << "," << get(i)[1] << ")" << " dist=" << dist << endl;
      break;
    }
  }
//  for (int k = 0; k < K; k++)
//    Log::m_log << "knn=" << knnIdx[k] << " min=" << minBound[k] << endl;
}
